package com.youlu.campus.service.operator.impl;

import com.alibaba.fastjson.JSON;
import com.mongodb.client.result.UpdateResult;
import com.youlu.campus.entity.ActivityInfo;
import com.youlu.campus.entity.OperatorTask;
import com.youlu.campus.entity.UserCaRecord;
import com.youlu.campus.entity.VO.req.OperatorTaskQueryVO;
import com.youlu.campus.service.activity.ActivityService;
import com.youlu.campus.service.operator.OperatorTaskService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.stereotype.Service;

import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;

@Slf4j
@Service
public class OperatorTaskServiceImpl implements OperatorTaskService {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private ActivityService activityService;

    @Override
    public Page<OperatorTask> list(OperatorTaskQueryVO req) {
        log.info(":>>> 开始获取运营操作任务列表:{}", JSON.toJSON(req));
        Query query = new Query();
        query.addCriteria(Criteria.where("deleted").ne(Boolean.TRUE));
        if (StringUtils.isNotBlank(req.getActivityId())) {
            query.addCriteria(Criteria.where("activityId").is(req.getActivityId()));
        }
        if (StringUtils.isNotBlank(req.getType())) {
            query.addCriteria(Criteria.where("type").is(req.getType()));
        }
        if (StringUtils.isNotBlank(req.getStatus())) {
            query.addCriteria(Criteria.where("status").is(req.getStatus()));
        }
        if (StringUtils.isNotBlank(req.getDesc())) {
            Pattern pattern = Pattern.compile("^.*" + req.getDesc() + ".*$");
            query.addCriteria(Criteria.where("desc").regex(pattern));
        }
        if (StringUtils.isNotBlank(req.getOptUser())) {
            query.addCriteria(Criteria.where("optUser").is(req.getOptUser()));
        }
        long count = this.mongoTemplate.count(query, OperatorTask.class);
        PageRequest pageRequest = PageRequest.of(req.getPage() - 1, req.getPageSize());
        if (count == 0) {
            return PageableExecutionUtils.getPage(new ArrayList<>(), pageRequest, () -> count);
        }
//        query.with(new Sort(Sort.Direction.DESC, "createdTime"));
        Sort sort=Sort.by(Sort.Direction.DESC, "createdTime");
        query.with(sort);
        query.with(pageRequest);
        List<OperatorTask> list = this.mongoTemplate.find(query, OperatorTask.class);
        return PageableExecutionUtils.getPage(list, pageRequest, () -> count);
    }

    @Override
    public OperatorTask findOne(@NotNull String id) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        return mongoTemplate.findOne(query, OperatorTask.class);
    }

    @Override
    public boolean create(@NotNull OperatorTask req) {
        if (StringUtils.isBlank(req.getActivityId())) {
            return false;
        }
        ActivityInfo activityInfo=activityService.findOne(req.getActivityId());
        if(Objects.nonNull(activityInfo)){
            req.setActivityName(activityInfo.getName());
        }
        req.setId(null);
        req.setCreatedTime(new Date());
        req.setStatus("todo");
        req = mongoTemplate.insert(req);
        if (StringUtils.isBlank(req.getId())) {
            return false;
        }
        return true;
    }

    @Override
    public boolean update(@NotNull OperatorTask req) {
        if (StringUtils.isBlank(req.getId())) {
            return false;
        }
        OperatorTask task = this.findOne(req.getId());
        if (Objects.isNull(task)) {
            log.error(":>>> 运行操作任务不存在:{}", req.getId());
            return false;
        }
        Query query = new Query().addCriteria(Criteria.where("id").is(req.getId()));
        Update update = new Update();
        if (StringUtils.isNotBlank(req.getDesc())) {
            update.set("desc", req.getDesc());
        }
        if (Objects.nonNull(req.getDeleted())) {
            update.set("deleted", req.getDeleted());
        }
        if (Objects.nonNull(req.getDeletedTime())) {
            update.set("deletedTime", req.getDeletedTime());
        }
        if (StringUtils.isNotBlank(req.getStatus())) {
            update.set("status", req.getStatus());
        }
        if (Objects.nonNull(req.getConditions())) {
            update.set("conditions", req.getConditions());
        }
        if (Objects.nonNull(req.getActions())) {
            update.set("actions", req.getActions());
        }
        if (Objects.nonNull(req.getQuery())) {
            update.set("query", req.getQuery());
        }
        if (Objects.nonNull(req.getUpdate())) {
            update.set("update", req.getUpdate());
        }
        update.set("updatedTime", new Date());
        return mongoTemplate.updateFirst(query, update, OperatorTask.class).getModifiedCount() > 0 ? true : false;
    }

    @Override
    public boolean delete(@NotNull String id) {
        OperatorTask exist = this.findOne(id);
        if (Objects.isNull(exist)) {
            log.error(":>>> 运营操作任务不存在:{}", id);
            return false;
        }
        if (!"todo".equals(exist.getStatus())) {
            log.error(":>>> 运营操作任务状态不是待执行不能删除:{}", id);
            return false;
        }
        OperatorTask deleted = new OperatorTask();
        deleted.setDeleted(true);
        deleted.setId(id);
        deleted.setDeletedTime(new Date());
        return this.update(deleted);
    }

    @Override
    public boolean stop(String id) {
        return false;
    }

    @Override
    public boolean start(String id) {
        Date date = new Date();
        OperatorTask task = this.findOne(id);
        if (Objects.isNull(task)) {
            log.error(":>>> 运行操作任务不存在:{}", id);
            return false;
        }
        if (!"todo".equals(task.getStatus())) {
            log.error(":>>> 操作任务状态错误:{}", id);
            return false;
        }
        /**
         * digital-ca-info:电子证书信息
         * order-tips
         */
        switch (task.getType()) {
            case "digital-ca-info": {
                if (task.getActions().containsKey("caTime")) {
                    String caTime = (String) task.getActions().get("caTime");
                    Query q = new Query();
                    boolean updated = false;
                    if (task.getConditions().containsKey("receiveStartTime") && task.getConditions().containsKey("receiveEndTime")) {
                        Criteria criteria = new Criteria().andOperator(Criteria.where("createdTime").gte((Date) task.getConditions().get("receiveStartTime")), Criteria.where("createdTime").lte((Date) task.getConditions().get("receiveEndTime")));
                        q.addCriteria(criteria);
                        updated = true;
                    } else if (task.getConditions().containsKey("receiveStartTime")) {
                        q.addCriteria(Criteria.where("createdTime").gte((Date) task.getConditions().get("receiveStartTime")));
                        updated = true;
                    } else if (task.getConditions().containsKey("receiveEndTime")) {
                        q.addCriteria(Criteria.where("createdTime").lte((Date) task.getConditions().get("receiveEndTime")));
                        updated = true;
                    }
                    if (updated) {
                        q.addCriteria(Criteria.where("digitalCa").is(Boolean.TRUE));
                        Long count = mongoTemplate.count(q, UserCaRecord.class);
                        OperatorTask taskU = new OperatorTask();
                        taskU.setId(id);
                        taskU.setCount(count);
                        taskU.setQuery(q);
                        taskU.setUpdatedTime(date);
                        Update update = new Update();
                        update.set("caTime", caTime);
                        update.set("updatedTime", date);
                        UpdateResult result = mongoTemplate.updateMulti(q, update, UserCaRecord.class);
                        taskU.setStatus("done");
                        taskU.setUpdate(update);
                        taskU.setDesc("查询数量:"+count+",实际更新数量:"+result.getModifiedCount());
                        this.update(taskU);
                    }
                }
                break;
            }

            case "order-tips": {
                break;
            }

            default:
                break;
        }
        return true;
    }
}
